package others.swing.p025;

import java.awt.*;
import javax.swing.*;
import java.io.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.UIManager.*;
import java.util.Vector;

///////////////////////绘图///////////////////////////
// 添加窗口和画板组件
class DrawFrame extends JFrame {
    public DrawFrame() {
        DrawPanel panel = new DrawPanel();
        add(panel);
        setTitle("简单JAVA画板");
        setBounds(100, 100, 800, 600);//窗口大小
        setVisible(true);//显示可见
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//程序的退出
    }
}

// 定义绘画点的基本属性，Serializable接口是启用其序列化功能的接口，没有实现此接口的类将不能使它们的任一状态被序列化或逆序列化。
class position implements Serializable {
    int x, y, type;
    String s;
    Color color;
}

// 定义画板组件，监听、MouseListener是鼠标点击事件的监听者，也就是单击，双击，单击后弹起之类的动作就需要这个监听者,总之就是要点击鼠标的。
//MouseMotionListener是鼠标移动事件的监听者，也就是moveover,moveout之类的事件，也就是只移动鼠标不点鼠标的。
class DrawPanel extends JPanel implements ActionListener, MouseListener, MouseMotionListener {
    JMenuBar mb;// 菜单栏
    JMenu menu1, menu2, menu3;//文件、编辑、帮助按钮
    JMenuItem i1, i2, i3, i4;
    JPanel jp1; // 工具栏
    public JButton anj0, anj2, anj3, anj4, anj5, anj6, anj7, anj8, anj9, anj10;//按钮
    JLabel l1, lcolor;
    Vector<position> thedraw = new Vector<position>(); // 保存画图轨迹的数组
    int style = 0; // 保存画图类型，默认为画笔
    int x1 = 0;// 保存点的坐标
    int x2 = 0;
    int y1 = 0;
    int y2 = 0;
    String input = "";// 默认输入文字内容
    Color linecolor = Color.BLACK; // 默认线的颜色：黑色

    public DrawPanel() {
        setBackground(Color.WHITE);//背景板的颜色
        setLayout(new BorderLayout());//JFrame是Windows类的子类，默认布局是BorderLayout布局
        setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));//鼠标简单控制

        // 上部菜单栏
        mb = new JMenuBar();
        mb.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));

        add(mb, BorderLayout.NORTH);

        // 加入菜单栏的组件
        menu1 = new JMenu("  文件     ");
        menu2 = new JMenu("  编辑     ");
        menu3 = new JMenu("  帮助     ");
        i1 = new JMenuItem("打开                    ");
        i2 = new JMenuItem("保存                    ");
        i3 = new JMenuItem("清空                    ");
        i4 = new JMenuItem("关于简单JAVA画板                    ");
        menu1.add(i1);
        menu1.addSeparator();//菜单中横线分隔符号,打开文件按钮之后，再打开和保存之间的横线
        menu1.add(i2);
        menu2.add(i3);
        menu3.add(i4);
        mb.add(menu1);
        mb.add(menu2);
        mb.add(menu3);
        add(mb, BorderLayout.NORTH);

        // 侧边工具栏
        jp1 = new JPanel();
        jp1.setBackground(Color.LIGHT_GRAY);//侧边工具栏的背景是灰色
        jp1.setLayout(new BoxLayout(jp1, BoxLayout.Y_AXIS));//BoxLayout：盒式布局
        jp1.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));//鼠标移到相应的位置,鼠标形状为默认

        add(jp1, BorderLayout.WEST);

        // 加入工具栏的组件
        anj0 = new JButton("画笔");
        anj2 = new JButton("橡皮");
        anj3 = new JButton("文字");
        anj4 = new JButton("直线");
        anj5 = new JButton("矩形");
        anj6 = new JButton("圆矩");
        anj7 = new JButton("椭圆");
        anj10 = new JButton("");
        lcolor = new JLabel("■");// 会变色的方块
        l1 = new JLabel("       颜色");
        anj10.add(lcolor);//将按钮控件依次加载到窗体中，各个控件依据加载顺序在窗体上一字排开，超过窗体宽度时，自动换到下一行
        anj10.add(l1);
        jp1.add(anj0);
        jp1.add(anj2);
        jp1.add(anj3);
        jp1.add(anj4);
        jp1.add(anj5);
        jp1.add(anj6);
        jp1.add(anj7);
        jp1.add(anj10);
        // 事件处理
        i1.addActionListener(this);
        i2.addActionListener(this);
        i3.addActionListener(this);
        i4.addActionListener(this);
        anj0.addActionListener(this);
        anj2.addActionListener(this);
        anj3.addActionListener(this);
        anj4.addActionListener(this);
        anj5.addActionListener(this);
        anj6.addActionListener(this);
        anj7.addActionListener(this);
        anj10.addActionListener(this);
        addMouseListener(this);
        addMouseMotionListener(this);
    }

    // 记录鼠标选择的功能
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == anj0)
            style = 0;
        else if (e.getSource() == anj2)
            style = 2;
        else if (e.getSource() == anj3) {
            style = 3;
            input = JOptionPane.showInputDialog("输入文字后在画板上点击放置");
        } else if (e.getSource() == anj4)
            style = 4;
        else if (e.getSource() == anj5)
            style = 5;
        else if (e.getSource() == anj6)
            style = 6;
        else if (e.getSource() == anj7)
            style = 7;
        else if (e.getSource() == anj10) {
            linecolor = JColorChooser.showDialog(null, "请选择颜色", Color.BLACK);
            lcolor.setForeground(linecolor);
        } else if (e.getActionCommand()
                .equals("关于简单JAVA画板                    ")) {
            JOptionPane.showMessageDialog(null,
                    "这是一个简单的JAVA画板。\n整理者：Jack魏 \n https://jackwei.blog.csdn.net/ ", " 关于 ",
                    JOptionPane.INFORMATION_MESSAGE);
        } else if (e.getActionCommand().equals("清空                    ")) {
            thedraw.removeAllElements();
        } else if (e.getActionCommand().equals("保存                    ")) {
            JFileChooser sfc = new JFileChooser();
            int flag = -1;
            // 显示保存文件的对话框
            try {
                flag = sfc.showSaveDialog(this);
            } catch (HeadlessException he) {
                System.out.println("Save File Dialog Exception!");
            }
            // 获取选择文件的路径
            if (flag == JFileChooser.APPROVE_OPTION) {
                String filename = sfc.getSelectedFile().getPath();
                try {
                    FileOutputStream fos = new FileOutputStream(filename);
                    ObjectOutputStream oos = new ObjectOutputStream(fos);
                    oos.writeObject(thedraw);
                    oos.close();
                } catch (Exception es) {
                    System.out.println(es);
                }
            }
        } else if (e.getActionCommand().equals("打开                    ")) {
            JFileChooser ofc = new JFileChooser();
            int flag = -1;
            try {
                flag = ofc.showOpenDialog(this);
            } catch (HeadlessException he) {
                System.out.println("Save File Dialog Exception!");
            }
            // 获取选择文件的路径
            if (flag == JFileChooser.APPROVE_OPTION) {
                String filename = ofc.getSelectedFile().getPath();
                try {
                    FileInputStream fis = new FileInputStream(filename);
                    ObjectInputStream ois = new ObjectInputStream(fis);
                    thedraw = (Vector<position>) ois.readObject();
                    ois.close();
                } catch (Exception es) {
                    System.out.println(es);
                }
            }
        }
        repaint();// 刷新画板
    }

    // paintComponent方法调用绘制方法使在容器内绘制而不超出容器
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        draw((Graphics2D) g);
    }

    // 从数组中取出一个点后画图
    public void draw(Graphics2D g) {
        int n = thedraw.size();
        position p;
        for (int i = 0; i < n; i++) {
            try {
                p = thedraw.get(i);
                if (p.type == 0) {// 画笔
                    x1 = x2 = p.x;
                    y1 = y2 = p.y;
                    while (p.type == 0) {
                        x2 = p.x;
                        y2 = p.y;
                        Line2D t = new Line2D.Double(x1, y1, x2, y2);
                        g.setColor(p.color);
                        g.draw(t);// 递归画图
                        i++;
                        if (i == n) {
                            i--;
                            break;
                        }
                        p = thedraw.get(i);
                        x1 = x2;
                        y1 = y2;
                    }
                }
                if (p.type == 2) {// 橡皮
                    while (p.type == 2) {
                        g.setColor(Color.WHITE);
                        g.drawString("■", p.x, p.y);// 采用字符使点变大
                        i++;
                        if (i == n) {
                            i--;
                            break;
                        }
                        p = thedraw.get(i);
                    }
                }
                if (p.type == 3) {// 文字
                    while (p.type == 3) {
                        g.setColor(p.color);
                        g.drawString(p.s, p.x, p.y);// 点状绘制实时字符
                        i++;
                        if (i == n) {
                            i--;
                            break;
                        }
                        p = thedraw.get(i);
                    }
                }
                if (p.type == 4) {// 直线
                    x1 = p.x;
                    y1 = p.y;
                    i++;
                    p = thedraw.get(i);
                    x2 = p.x;
                    y2 = p.y;
                    if (p.type == 4) {// 不存在翻转问题，故不用交换坐标
                        Line2D t = new Line2D.Double(x1, y1, x2, y2);
                        g.setColor(p.color);
                        g.draw(t);
                        thedraw.remove(i);
                    } else if (p.type == -1) {
                        Line2D t = new Line2D.Double(x1, y1, x2, y2);
                        g.setColor(p.color);
                        g.draw(t);
                    } else
                        i--;
                }
                if (p.type == 5) {// 矩形
                    x1 = p.x;
                    y1 = p.y;
                    i++;
                    p = thedraw.get(i);
                    x2 = p.x;
                    y2 = p.y;
                    if (x2 < x1) {// 交换坐标使图形能上下左右翻转
                        int temp;
                        temp = x1;
                        x1 = x2;
                        x2 = temp;
                    }
                    if (y2 < y1) {
                        int temp;
                        temp = y1;
                        y1 = y2;
                        y2 = temp;
                    }
                    if (p.type == 5) {// 鼠标按下则动态变化
                        Rectangle2D t = new Rectangle2D.Double(x1, y1, x2 - x1, y2 - y1);
                        g.setColor(p.color);
                        g.draw(t);
                        thedraw.remove(i);
                    } else if (p.type == -1) {// 鼠标松开则固定绘图
                        Rectangle2D t = new Rectangle2D.Double(x1, y1, x2 - x1, y2 - y1);
                        g.setColor(p.color);
                        g.draw(t);
                    } else
                        i--;
                }
                if (p.type == 6) {// 圆角矩形
                    x1 = p.x;
                    y1 = p.y;
                    i++;
                    p = thedraw.get(i);
                    x2 = p.x;
                    y2 = p.y;
                    if (x2 < x1) {
                        int temp;
                        temp = x1;
                        x1 = x2;
                        x2 = temp;
                    }
                    if (y2 < y1) {
                        int temp;
                        temp = y1;
                        y1 = y2;
                        y2 = temp;
                    }
                    if (p.type == 6) {
                        RoundRectangle2D t = new RoundRectangle2D.Double(x1, y1, x2 - x1, y2 - y1, 20, 20);
                        g.setColor(p.color);
                        g.draw(t);
                        thedraw.remove(i);
                    } else if (p.type == -1) {
                        RoundRectangle2D t = new RoundRectangle2D.Double(x1, y1, x2 - x1, y2 - y1, 20, 20);
                        g.setColor(p.color);
                        g.draw(t);
                    } else
                        i--;
                }
                if (p.type == 7) {// 椭圆
                    x1 = p.x;
                    y1 = p.y;
                    i++;
                    p = thedraw.get(i);
                    x2 = p.x;
                    y2 = p.y;
                    if (x2 < x1) {
                        int temp;
                        temp = x1;
                        x1 = x2;
                        x2 = temp;
                    }
                    if (y2 < y1) {
                        int temp;
                        temp = y1;
                        y1 = y2;
                        y2 = temp;
                    }
                    if (p.type == 7) {
                        Ellipse2D t = new Ellipse2D.Double(x1, y1, x2 - x1, y2 - y1);
                        g.setColor(p.color);
                        g.draw(t);
                        thedraw.remove(i);
                    } else if (p.type == -1) {
                        Ellipse2D t = new Ellipse2D.Double(x1, y1, x2 - x1, y2 - y1);
                        g.setColor(p.color);
                        g.draw(t);
                    } else
                        i--;
                }
            } catch (Exception e) {
                System.out.println(e);
            }
        }
    }

    public void mouseClicked(MouseEvent e) {
    }

    public void mouseEntered(MouseEvent e) {
    }

    // 鼠标按下记录画图轨迹
    public void mousePressed(MouseEvent e) {
        position p = new position();
        p.x = e.getX();
        p.y = e.getY();
        p.type = style;
        p.s = input;
        p.color = linecolor;
        thedraw.add(p);
    }

    public void mouseExited(MouseEvent e) {
    }

    // 鼠标松开则type = -1，停止画图，但仍记录轨迹
    public void mouseReleased(MouseEvent e) {
        position p = new position();
        p.x = e.getX();
        p.y = e.getY();
        p.type = -1;
        p.s = input;
        p.color = linecolor;
        thedraw.add(p);
        repaint();
    }

    public void mouseMoved(MouseEvent e) {
    }

    // 鼠标拖动记录画图轨迹
    public void mouseDragged(MouseEvent e) {
        position p = new position();
        p.x = e.getX();
        p.y = e.getY();
        if (style == 3)
            p.type = -1;// 禁止文字拖动
        else
            p.type = style;
        p.s = input;
        p.color = linecolor;
        thedraw.add(p);
        repaint();
    }
}

///////////////////////图片///////////////////////////
public class Picture extends JFrame implements ActionListener {
    private JLabel imagelabel;
    private JPanel panel;
    private int i = 0;
    String filename;
    File file;
    private ImageIcon image;
    private JButton startbutton, stopbutton, previousbutton, nextbutton;
    private JMenuBar menubar;
    private JMenu menu;
    private JMenuItem menuitemopen, menuitemexit, penopen;
    private JFileChooser chooser;

    public Picture() {
        imagelabel = new JLabel();
        panel = new JPanel();//面板
        image = new ImageIcon();//图标
        startbutton = new JButton("放大");//按钮
        stopbutton = new JButton("缩小");
        previousbutton = new JButton("上一张");
        nextbutton = new JButton("下一张");
        menubar = new JMenuBar();//菜单栏
        menu = new JMenu("文件");
        menuitemopen = new JMenuItem("打开文件");
        menuitemexit = new JMenuItem("退出");
        penopen = new JMenuItem("打开画板");
        chooser = new JFileChooser();
    }

    public void launchPictureTest() {
        Container c = getContentPane();//初始化一个容器，用来在容器上添加一些控件.
        startbutton.addActionListener(this);
        stopbutton.addActionListener(this);
        previousbutton.addActionListener(this);
        nextbutton.addActionListener(this);
        menuitemopen.addActionListener(this);
        menuitemexit.addActionListener(this);
        penopen.addActionListener(this);
        menubar.add(menu);
        menu.add(menuitemopen);
        menu.add(menuitemexit);
        menu.add(penopen);
        imagelabel.setIcon(image);
        imagelabel.setHorizontalAlignment(SwingConstants.CENTER);
        c.add(imagelabel, "Center");
        panel.add(previousbutton);//上一张
        panel.add(nextbutton);//下一张
        panel.add(startbutton);//放大
        panel.add(stopbutton);//缩小
        c.add(panel, "South");
        chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
        chooser.setCurrentDirectory(new File(".")); //设置文件选择器当前目录
        chooser.setFileFilter(new javax.swing.filechooser.FileFilter() {
            public boolean accept(File file) {  //可接受的文件类型
                String name = file.getName().toLowerCase(); //获取文件名
                return name.endsWith(".gif") || name.endsWith(".jpg") || name.endsWith(".jpeg") || file.isDirectory();
            }

            public String getDescription() {
                return "图像文件";
            }
        });
        setJMenuBar(menubar);
        setSize(800, 600);//窗体尺寸
        setLocation(100, 100);//将组件移到x=100,y=100的位置
        setTitle(filename);//设置文件名
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//退出
        setVisible(true);
    }

    public void actionPerformed(ActionEvent e) {
        Object source = e.getSource();//事件源
        if (source == menuitemopen) {        //文件打开
            int result = chooser.showOpenDialog(this); //显示文件选择对话框
            if (result == JFileChooser.APPROVE_OPTION) {
                String filename = chooser.getSelectedFile().getAbsolutePath();
                image = new ImageIcon(filename);
                ImageIcon icon = new ImageIcon();
                icon = image;
                double widthratio = image.getIconWidth() * 1.0 / imagelabel.getWidth();//打开图片大小的设置
                double heightratio = image.getIconHeight() * 1.0 / imagelabel.getWidth();
                if (widthratio <= 1 && heightratio <= 1) {   //图片大小的限定
                    imagelabel.setIcon(image);
                }
                int width = -1, height = -1;
                if (heightratio >= widthratio) {
                    height = imagelabel.getHeight();
                } else {
                    width = imagelabel.getWidth();
                }
                image = new ImageIcon(icon.getImage().getScaledInstance(width, height, Image.SCALE_SMOOTH));
                imagelabel.setIcon(image);

            }
        } else if (source == penopen)//画板打开
        {
            try {       // 优化UI效果
                for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                    if ("Nimbus".equals(info.getName())) {
                        UIManager.setLookAndFeel(info.getClassName());
                        break;
                    }
                }
            } catch (Exception eee) {
                System.out.println(eee);
            }
            new DrawFrame();
        } else if (source == menuitemexit) {    //退出
            System.exit(1);
        } else if (source == previousbutton) {    //上一张
            File[] files;
            file = chooser.getSelectedFile().getParentFile();
            files = file.listFiles();
            if (i > 0 && i < files.length)
                i--;
            String filename = files[i].getAbsolutePath();
            image = new ImageIcon(filename);
            ImageIcon icon = new ImageIcon();
            icon = image;
            double widthratio = image.getIconWidth() * 1.0 / imagelabel.getWidth();
            double heightratio = image.getIconHeight() * 1.0 / imagelabel.getWidth();
            if (widthratio <= 1 && heightratio <= 1) {
                imagelabel.setIcon(image);
            }
            int width = -1, height = -1;
            if (heightratio >= widthratio) {
                height = imagelabel.getHeight();
            } else {
                width = imagelabel.getWidth();
            }
            image = new ImageIcon(icon.getImage().getScaledInstance(width, height, Image.SCALE_SMOOTH));
            imagelabel.setIcon(image);
        } else if (source == nextbutton) {    //下一张
            File[] files;
            file = chooser.getSelectedFile().getParentFile();
            files = file.listFiles();
            if (i >= 0 && i < files.length)
                i++;
            String filename = files[i].getAbsolutePath();
            image = new ImageIcon(filename);
            ImageIcon icon = new ImageIcon();
            icon = image;
            double widthratio = image.getIconWidth() * 1.0 / imagelabel.getWidth();
            double heightratio = image.getIconHeight() * 1.0 / imagelabel.getWidth();
            if (widthratio <= 1 && heightratio <= 1) {
                imagelabel.setIcon(image);
            }
            int width = -1, height = -1;
            if (heightratio >= widthratio) {
                height = imagelabel.getHeight();
            } else {
                width = imagelabel.getWidth();
            }
            image = new ImageIcon(icon.getImage().getScaledInstance(width, height, Image.SCALE_SMOOTH));
            imagelabel.setIcon(image);

        } else if (source == startbutton) {    //放大
            File[] files;
            file = chooser.getSelectedFile().getParentFile();
            files = file.listFiles();
            String filename = files[i].getAbsolutePath();
            image = new ImageIcon(filename);
            ImageIcon icon = new ImageIcon();
            icon = image;
            double widthratio = image.getIconWidth() * 1.0 / imagelabel.getWidth();
            double heightratio = image.getIconHeight() * 1.0 / imagelabel.getWidth();
            if (widthratio <= 1 && heightratio <= 1) {
                imagelabel.setIcon(image);
            }
            int width = -1, height = -1;
            if (heightratio >= widthratio) {
                height = imagelabel.getHeight() * 2;
            } else {
                width = imagelabel.getWidth() * 2;
            }
            image = new ImageIcon(icon.getImage().getScaledInstance(width, height, Image.SCALE_SMOOTH));
            imagelabel.setIcon(image);
        } else if (source == stopbutton) {    //缩小
            File[] files;
            file = chooser.getSelectedFile().getParentFile();
            files = file.listFiles();
            String filename = files[i].getAbsolutePath();
            image = new ImageIcon(filename);
            ImageIcon icon = new ImageIcon();
            icon = image;
            double widthratio = image.getIconWidth() * 1.0 / imagelabel.getWidth();
            double heightratio = image.getIconHeight() * 1.0 / imagelabel.getWidth();
            if (widthratio <= 1 && heightratio <= 1) {
                imagelabel.setIcon(image);
            }
            double width = -1, height = -1;
            if (heightratio >= widthratio) {
                height = imagelabel.getHeight() * 0.5;
            } else {
                width = imagelabel.getWidth() * 0.5;
            }
            image = new ImageIcon(icon.getImage().getScaledInstance((int) width, (int) height, Image.SCALE_SMOOTH));
            imagelabel.setIcon(image);
        }
    }

    public static void main(String[] arges) {
        Picture pe = new Picture();    //图片
        pe.launchPictureTest();    //画板
    }
}

